import { isDate, isArray, isNull, isUndefined, isObject, isURLSearchParams } from './util'

interface URLOrigin {
  protocol: string
  host: string
}

function encode(val: string): string {
  // 对于字符 @、:、$、逗号、空格(装换为+)、[、]，我们是允许出现在 url 中的，不希望被 encode
  return encodeURIComponent(val)
    .replace(/%40/g, '@')
    .replace(/%3A/gi, ':')
    .replace(/%24/g, '$')
    .replace(/%2C/gi, ',')
    .replace(/%20/g, '+')
    .replace(/%5B/gi, '[')
    .replace(/%5D/gi, ']')
}

export function buildURL(
  url: string,
  params?: any,
  paramsSerializer?: (params: any) => string
): string {
  if (!params) {
    return url
  }
  let serializedParams
  if (paramsSerializer) {
    serializedParams = paramsSerializer(params)
  } else if (isURLSearchParams(params)) {
    serializedParams = params.toString()
  } else {
    if (isObject(params)) {
      let parts: string[] = []
      Object.keys(params).forEach(key => {
        let val = params[key]
        let values: string[] = []
        if (isNull(val) || isUndefined(val)) return
        if (isArray(val)) {
          key = key + '[]'
          values = val
        } else {
          values = [val]
        }
        values.forEach(item => {
          if (isObject(item)) {
            item = JSON.stringify(item)
          } else if (isDate(item)) {
            item = (item as Date).toISOString()
          }
          parts.push(`${key}=${encode(item)}`)
        })
      })
      serializedParams = parts.join('&')
    }
  }
  if (serializedParams) {
    let hashIndex = url.indexOf('#')
    if (hashIndex !== -1) {
      url = url.slice(0, hashIndex)
    }
    url = url + (url.includes('?') ? '&' : '?') + serializedParams
  }
  return url
}

function resolveURL(url: string): URLOrigin {
  const domA = document.createElement('a')
  domA.setAttribute('href', url)
  const { protocol, host } = domA
  return {
    protocol,
    host
  }
}

const currentOrigin = resolveURL(window.location.href)

export function isURLSameOrigin(url: string) {
  const parsedOrigin = resolveURL(url)
  return (
    parsedOrigin.protocol === currentOrigin.protocol && parsedOrigin.host === currentOrigin.host
  )
}

export function isAbsoluteURL(url: string): boolean {
  return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url)
}

export function combineURL(baseURL: string, relativeURL?: string): string {
  return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL
}
